import { useRandom, GemsDom } from "../builder.js";
import { tabbarDict } from "../config/const.js";

export const createStore = () => {
  GemsDom.initStore(
    {
      current: tabbarDict.M,
      msgList: [],
      get msgListLast() {
        return this.msgList[this.msgList.length - 1];
      },
      seed: Date.now(),
      gameCore: null,
    },
    {
      pushMsg({ state, emit }, payload) {
        state.msgList.push({ id: Var.uuid(), ...payload });
        emit("msgListUpdate");
      },
      async gameStart({ state, emit }) {
        emit("pushMsg", { content: "进入游戏" });
        state.gameCore = new GameCore(state.seed);
      },
    }
  );
};

class GameCore {
  constructor(seed) {
    const [random] = useRandom(seed);
    this.#random = random;
    this.#initMapBlock();
  }
  static areaType = {
    forset: { label: "森林" },
    cave: { label: "洞穴" },
    hill: { label: "山丘" },
    lake: { label: "湖泊" },
    sea: { label: "海域" },
    plain: { label: "平原" },
    iceField: { label: "冰原" },
    cave: { label: "村庄" },
    city: { label: "城邦" },
  };
  static get areaTypeKeys() {
    return Object.keys(this.areaType);
  }
  #random;
  // 地图区块
  #mapBlock = new Map();
  #position = {
    x: 0,
    y: 0,
  };
  get currentMap() {
    return this.#mapBlock.get(
      this.#getNameByXY(this.#position.x, this.#position.y)
    );
  }
  // 初始化地图区块
  #initMapBlock() {
    const block = this.#genMapBlock(0, 0);
    console.table(block);
    this.#setMapBlock(block);
  }
  #setMapBlock(blockSrouce) {
    const that = this;
    const block = {
      ...blockSrouce,
      get name() {
        return that.#getNameByXY(this.position.x, this.position.y);
      },
    };
    this.#mapBlock.set(
      this.#getNameByXY(block.position.x, block.position.y),
      block
    );
  }
  #getRandomCharacter() {
    const integer = this.#randomInteger(40869, 19968);
    return String.fromCharCode(integer);
  }
  #getRandomCharacters(length = 1) {
    let str = "";
    Var.times(length, () => {
      str += this.#getRandomCharacter();
    });
    return str;
  }
  #genMapBlock(x, y) {
    const explorelimit = this.#randomInteger(8, 1);
    const areas = [];
    Var.times(explorelimit, () => {
      const typeNum = this.#randomInteger(GameCore.areaTypeKeys.length);
      const type = GameCore.areaTypeKeys[typeNum];
      areas.push({
        id: Var.uuid(),
        type,
        name: this.#getRandomCharacters(this.#randomInteger(5, 2)),
        hasDiscovered: true,
        hasOccupied: false,
        favorability: 0,
        get typeLabel() {
          return GameCore.areaType[this.type].label;
        },
      });
    });
    return {
      position: {
        x,
        y,
      },
      areas,
    };
  }
  #randomInteger(max, min = 0) {
    return Math.floor(this.#random() * (max - min)) + min;
  }
  #getNameByXY(x, y) {
    return `${x}-${y}`;
  }
  #getXYByName(name) {
    const [x, y] = name.split("-");
    return { x, y };
  }
}
